package wassalt.client;

import wassalt.Services.*;
import static wassalt.Utils.User.loadUser;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import org.apache.http.HttpStatus;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import static wassalt.Utils.AppConstants.*;

public class PermissionsActivity extends ListActivity {

	ProgressDialog dialog;
	String[] phones;
	String[] values;
	ContextMenu contextMenu;
	private BroadcastReceiver receiver;
	static final String HTTP_PERMISSIONS_GET_FILTER = "HTTP_PERMISSION_FILTER";
	static final String HTTP_PERMISSIONS_UPDATE_FILTER = "HTTP_PERMISSIONS_UPDATE_FILTER";
	static final String receiverPhoneArg = "receiverMobile";
	static final String senderPhoneArg = "senderMobile";
	static final String serverSetPermissionURL = "/Permissions/setPermission";
	/**
	 * permissions images ids
	 */
	int images[];
	/**
	 * The text that appears to represent a permission, e.g. Always allow,
	 * Always ask and Never allow.
	 */
	String permissionsText[];

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		init();
		registerForContextMenu(getListView());
		getPermissionsFromServer();
		setTitle(getString(R.string.permissionsTitle));
	}

	/**
	 * Initializes required variables
	 * 
	 * @author Loai Ghoraba
	 */
	public void init() {
		permissionsText = getResources()
				.getStringArray(R.array.permissionsText);
		images = new int[] { R.drawable.allow, R.drawable.ask, R.drawable.never };
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		contextMenu = menu;
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;

		int groupId = 1;
		menu.setGroupCheckable(groupId, true, true);
		// add permissions items, the id here is i
		for (int i = 0; i < permissionsText.length; i++)
			menu.add(groupId, i, 0, permissionsText[i]);
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.permissions_menu, menu);
		LayoutInflater layoutInflater = LayoutInflater.from(this);
		final View view = layoutInflater.inflate(
				R.layout.permission_context_menu_header, null);
		TextView tv = (TextView) view.findViewById(R.id.permission_menu_header);
		String title = getString(R.string.perm_change)
				+ ((UserPermission) getListAdapter().getItem((int) info.id))
						.getName();
		tv.setText(title);
		menu.setHeaderView(view);
	}

	/**
	 * Gets the permissions from the service
	 * 
	 * @author loai
	 */
	public void getPermissionsFromServer() {
		dialog = ProgressDialog.show(PermissionsActivity.this, "",
				getString(R.string.loadingPermissionsDialog), true, false);
		String path = "/Permissions/getUsersPermissions?phone="
				+ loadUser(getApplicationContext()).getPhone();
		Intent serviceIntent = new Intent(this, HTTPService.class);
		serviceIntent.setAction(HTTP_PERMISSIONS_GET_FILTER);
		serviceIntent.putExtra(URL, getString(R.string.server_url) + path);
		Log.e(PermissionsActivity.class.getName(),
				"Before calling HTTP service");
		startService(serviceIntent);
	}

	public static String getStackTrace(Exception e) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		e.printStackTrace(pw);
		return sw.toString();
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		Log.e("Menu item selected", (String) item.getTitle());
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
				.getMenuInfo();
		updatePermission(phones[(int) info.id], item.getItemId(), (int) info.id);
		return true;
	}

	/**
	 * Updates the permission of the selected contact on the server
	 * 
	 * @author loai
	 * @param phone
	 *            the phone number of the user to change the permission
	 * @param permission
	 *            the new permission of this user to set
	 */
	public void updatePermission(final String phone, final int permission,
			final int position) {
		// get it from selected position
		dialog = ProgressDialog.show(PermissionsActivity.this, "",
				getString(R.string.updatingPermission), true, false);
		Intent serviceIntent = new Intent(this, HTTPService.class);
		// add URL parameter
		serviceIntent.putExtra(receiverPhoneArg, phone);
		serviceIntent.putExtra(senderPhoneArg,
				loadUser(getApplicationContext()).getPhone());
		// Set the filter
		serviceIntent.setAction(HTTP_PERMISSIONS_UPDATE_FILTER);
		// Set the url to be called
		serviceIntent.putExtra(URL, getString(R.string.server_url)
				+ serverSetPermissionURL);
		serviceIntent.putExtra("permission", permission);
		Log.e("Sent params", position + " " + permission);
		startService(serviceIntent);
	}

	protected void setPermissions(final String responseStr) {
		ArrayList<UserPermission> usersPermissions = new ArrayList<UserPermission>();
		try {
			JSONArray jsonArray = new JSONArray(responseStr);
			values = new String[jsonArray.length()];
			phones = new String[jsonArray.length()];
			for (int i = 0; i < jsonArray.length(); i++) {
				JSONObject js = jsonArray.getJSONObject(i);
				values[i] = "Phone: " + js.getString("phone")
						+ "\nPermission: " + js.getString("permission");
				phones[i] = js.getString("phone");
				usersPermissions.add(new UserPermission(js.getString("phone"),
						js.getString("name"), js.getInt("permission")));
				final ArrayList<UserPermission> ups = usersPermissions;
				PermissionsAdapter myAdapter = new PermissionsAdapter(
						PermissionsActivity.this,
						R.layout.permissions_list_row, ups);
				setListAdapter(myAdapter);
				Log.e("Setted", "Setted");
				if (dialog != null)
					dialog.dismiss();
				Log.e("Dismissed", "Dismissed");
			}
		} catch (Exception e) {
			Log.e("ERROR !!", e.getMessage());
		} finally {
			if (dialog != null)
				dialog.dismiss();
		}
	}

	private class HTTPReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			Log.e(HTTPReceiver.class.getName(), intent.getAction());
			int http_status = intent.getExtras().getInt(HTTP_STATUS);
			String action = intent.getAction();
			// If the HTTP request was successful, update
			if (http_status == HttpStatus.SC_OK) {
				if (action.equals(HTTP_PERMISSIONS_GET_FILTER)) {
					Log.e(HTTPReceiver.class.getName(), "In get");
					// Get the HTTP Response
					String responseStr = intent.getExtras().getString(
							HTTP_RESPONSE);
					setPermissions(responseStr);
				} else if (action.equals(HTTP_PERMISSIONS_UPDATE_FILTER)) {
					Log.e(HTTPReceiver.class.getName(), "In update");
					// Get the parameters sent to the HTTPServices
					String receiverPhone = intent.getExtras().getString(
							receiverPhoneArg);
					// Get the position of this person in the list
					PermissionsAdapter adapter = (PermissionsAdapter) getListAdapter();
					int position = 0;
					for (; position < adapter.permissions.size(); position++)
						if (adapter.get(position).phone.equals(receiverPhone))
							break;
					int permission = intent.getExtras().getInt("permission");
					// update the permission
					adapter.get(position).permission = permission;
					Log.e("Received params", position + " " + permission);
					// update the list view
					adapter.notifyDataSetChanged();
				}

			}
			// clean up
			if (dialog != null)
				dialog.dismiss();
		}

	}

	protected void onPause() {
		super.onPause();
		dialog = null;
		unregisterReceiver(receiver);
	}

	protected void onResume() {
		super.onResume();
		receiver = new HTTPReceiver();
		IntentFilter filter = new IntentFilter();
		// Add the filters
		filter.addAction(HTTP_PERMISSIONS_GET_FILTER);
		filter.addAction(HTTP_PERMISSIONS_UPDATE_FILTER);
		registerReceiver(receiver, filter);
	}

	private class UserPermission {
		@SuppressWarnings("unused")
		String phone;
		String name;
		int permission;

		public UserPermission(String phone, String name, int permission) {
			super();
			this.phone = phone;
			this.name = name;
			this.permission = permission;
		}

		public String getName() {
			return name;
		}

		public int getPermission() {
			return permission;
		}

	}

	private class PermissionsAdapter extends ArrayAdapter<UserPermission> {
		ArrayList<UserPermission> permissions;

		public PermissionsAdapter(Context context, int textViewResourceId,
				ArrayList<UserPermission> permissions) {
			super(context, textViewResourceId, permissions);
			this.permissions = permissions;
		}

		public UserPermission get(int index) {
			return permissions.get(index);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View v = convertView;
			if (v == null) {
				LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				v = vi.inflate(R.layout.permissions_list_row, null);
			}
			UserPermission userPermission = permissions.get(position);
			int index = userPermission.getPermission();
			TextView permissionTextview = (TextView) v
					.findViewById(R.id.permissionText);
			TextView nameTextview = (TextView) v.findViewById(R.id.nameText);
			ImageView image = (ImageView) v.findViewById(R.id.icon);
			nameTextview.setText(userPermission.getName());
			permissionTextview.setText(permissionsText[index]);
			image.setImageResource(images[index]);
			return v;
		}

	}
}
